/**
 * @file 标签页位置查找和移动工具
 * @description 提供标签页位置查找、移动和排序相关的工具函数
 * @author 黄敏
 * @version 1.0.0
 * @since 2025-08-22
 */

/**
 * 位置信息接口
 */
export interface TabPosition {
  groupId?: number
  index: number
}

/**
 * 类型保护函数：检查是否为标签页
 * @param obj 要检查的对象
 * @returns 是否为标签页
 */
export function isTab(obj: F2.tab.TabOrGroup | F2.tab.Create): obj is F2.tab.Entity {
  return 'webContentsId' in obj
}

/**
 * 类型保护函数：检查是否为分组
 * @param obj 要检查的对象
 * @returns 是否为分组
 */
export function isGroup(obj: F2.tab.TabOrGroup): obj is F2.tab.Group {
  return obj.type === 'group'
}

/**
 * 获取拖拽目标的位置信息
 * @param tabs 标签页或分组数组
 * @param tabId 标签页ID
 * @returns 位置信息或null
 */
export function findTabPosition(tabs: F2.tab.TabOrGroup[], tabId?: number): TabPosition | null {
  if (!tabId) return null
  // 查找在普通标签中的位置
  for (const [i, item] of tabs.entries()) {
    if (!item) continue

    // 普通标签
    if (item.id === tabId) {
      return { index: i }
    }

    if (item && isGroup(item)) {
      // 分组
      for (let j = 0; j < item.tabs.length; j++) {
        if (item.tabs[j]?.id === tabId) {
          return { groupId: item.id, index: j }
        }
      }
    }
  }
  return null
}

/**
 * 从当前位置移除标签页
 * @param tabs 标签页或分组数组
 * @param tabId 标签页ID
 * @returns 被移除的标签页或分组，如果未找到则返回null
 */
export function removeTabFromCurrentPosition(
  tabs: F2.tab.TabOrGroup[],
  tabId: number
): F2.tab.TabOrGroup | null {
  for (let i = 0; i < tabs.length; i++) {
    const item = tabs[i]
    if (!item) continue
    if (item.id === tabId) {
      return tabs.splice(i, 1)[0] as F2.tab.TabOrGroup
    } else if (isGroup(item)) {
      const tabIndex = item.tabs.findIndex(tab => isTab(tab) && tab.id === tabId)
      if (tabIndex !== -1) {
        // 上面已经判断isTab(tab)，所以这里断言一下，避免类型错误
        const removedTab = (item.tabs.splice(tabIndex, 1)[0] as F2.tab.Entity) || null

        // 如果分组变空，移除分组
        if (item.tabs.length === 0) {
          tabs.splice(i, 1)
        }
        return removedTab
      }
    }
  }
  return null
}

/**
 * 相对于另一个标签移动
 * @param tabs 标签页或分组数组
 * @param draggedTabId 被拖拽的标签页ID或对象
 * @param targetTabId 目标标签页ID
 * @param after 是否插入到目标标签页之后
 */
export function moveTabRelativeToAnother(
  tabs: F2.tab.TabOrGroup[],
  draggedTabId: number | F2.tab.TabOrGroup,
  targetTabId: number | undefined,
  after: boolean
): void {
  const draggedTab: F2.tab.TabOrGroup | null =
    typeof draggedTabId === 'number'
      ? removeTabFromCurrentPosition(tabs, draggedTabId)
      : draggedTabId

  if (!draggedTab) return

  // 找到目标标签的位置

  const targetPosition = findTabPosition(tabs, targetTabId)
  if (!targetPosition) {
    // 如果找不到目标位置，放到末尾
    tabs.push(draggedTab)
    return
  }

  if (targetPosition.groupId) {
    // 目标在分组内
    const group = tabs.find(item => isGroup(item) && item.id === targetPosition.groupId)
    if (group && 'tabs' in group) {
      const insertIndex = after ? targetPosition.index + 1 : targetPosition.index
      if (draggedTab.type === 'tab') {
        group.tabs.splice(insertIndex, 0, draggedTab)
      } else {
        // 如果找不到目标位置，放到末尾
        tabs.push(draggedTab)
      }
    }
  } else {
    // 目标在顶层
    const insertIndex = after ? targetPosition.index + 1 : targetPosition.index
    tabs.splice(insertIndex, 0, draggedTab)
  }
}

/**
 * 获取所有可见tab的线性列表（包括主区tab和所有分组内tab，顺序与UI一致）
 * @param tabs 标签页或分组数组
 * @returns 线性标签页数组
 */
export function getAllTabsLinear(tabs: F2.tab.TabOrGroup[]): F2.tab.Entity[] {
  const result: F2.tab.Entity[] = []
  for (const t of tabs) {
    if (isTab(t)) result.push(t)
    else if (isGroup(t)) {
      for (const tab of t.tabs) {
        if (isTab(tab)) result.push(tab)
      }
    }
  }

  return result
}
